package Command;

import java.util.ArrayList;
import java.util.Vector;

import DTO.Field;
import DTO.Row;
import DTO.Table;
import XML.XMLHelper;

public class Select extends Command {
	
	public Select(String str)
	{
		super(str);
	}
	
	private Table combineTables(Vector<Table> tables)
	{ 
		if(tables.size() == 1)
			return tables.get(0);
		
		Table mulTable = new Table("Mul", getDbName(), null, null);
		
		for(int i = 0 ; i < tables.size() - 1; i++)
		{
			for(int j = i + 1 ; j < tables.size(); j++)
			{
				if(tables.get(i).get_Name().equals(tables.get(j).get_Name()))
				{
					return null;
				}
			}
		}
		
		for(int i = 0 ; i < tables.size(); i++)
		{
			Vector<Field> fields = mulTable.get_Fields();
			fields.addAll(tables.get(i).get_Fields());
			
			Vector<Row> rows = mulTable.get_Rows();
			Vector<Row> addRows = tables.get(i).get_Rows();
			Vector<Row> mulRows = new Vector<Row>();
			
			for(int j = 0 ; j < rows.size(); j++)
			{
				Row row = rows.get(j);
				
				for(int k = 0; k < addRows.size(); k++)
				{
					Row r = row.clone();
					r.add_Fields(addRows.get(k).get_Fileds());
					mulRows.add(r);
				}
			}
			
			
			mulTable.set_Fields(fields);
			mulTable.set_Row(mulRows);
		}
		
		return mulTable;
	}
	public Object executeQuery()
	{		
		try
		{
			Object ret = "Select failed";
			String sql = getSql();
			
			// Check update keyword				
			String str1 = sql.trim();
			boolean merge = false;
			
			if(str1.toLowerCase().startsWith("select"))
			{
				
				int fromIndex = str1.toLowerCase().indexOf("from");
				
				String fieldToShow = str1.substring("select".length(), fromIndex);
				
				int whereIndex = str1.toLowerCase().indexOf("where");
				
				if(fromIndex > 0 )
				{
					String tableStr = str1.substring(fromIndex +"from".length());
					if(whereIndex > 0)
					{
						tableStr = str1.substring(fromIndex +"from".length(), whereIndex);
					}
					
					String[] tableStrs =  tableStr.split(",");
					Vector<Table> tables = new Vector<Table>();
					Vector<String> tableVars = new Vector<String>();
					
					for(int i = 0 ; i < tableStrs.length; i++)
					{
						Table table;
						String tableName = tableStrs[i].trim();
						tableName =  tableName.replaceAll(" +$", "");
						if(tableName.split(" ").length == 2)
						{
							tableVars.add(tableName.split(" ")[1]);
							if( (table = XMLHelper.GetTable(getDbName(), tableName.split(" ")[0])) != null)
								tables.add(table);
						}
						else
						{
							if( (table = XMLHelper.GetTable(getDbName(), tableName)) != null)
							{
								tables.add(table);
							}
						}
						
					}
					
					
					Table table = combineTables(tables);
					if(table == null)
						return null;
					
					Vector<Field> fields = table.get_Fields();
					String[] fieldStr = fieldToShow.split(",");
					Vector<String> fullFields = new Vector<String>();
					for(int i = 0 ; i < fields.size(); i++)
						fullFields.add(fields.get(i).get_Name());
					
					Vector<String> retFields = new Vector<String>();
					
					for(int i = 0 ; i < fieldStr.length; i++)
					{
						String fTemp = fieldStr[i].trim();
						fTemp = fTemp.replaceAll(" +$", "");
						if(fTemp.equals("*"))
						{
							retFields.addAll(fullFields);
						}
						else if(fullFields.contains(fTemp))
						{
							retFields.add(fTemp);
						}
					}
					
					if(whereIndex > 0 && tables.size() > 0)
					{
						
						String conditionParent = str1.substring(whereIndex + "where".length());
						
						if(merge)
						{
							int whereChildIndex = conditionParent.indexOf("where");
							String conditionChild = conditionParent.substring(whereChildIndex + "where".length());
							
							String[] conditionChilds = conditionChild.split(",");
							for(int i = 0 ; i < conditionChilds.length; i++)
							{
								conditionChilds[i] = conditionChilds[i].trim();
								conditionChilds[i] = conditionChilds[i].replaceAll(" +$", "");
							}
								
							// Phan cap
							
							// Tuong quan
							
						}
						else
						{

							Vector<Row> rows = Condition.ReversePoland(conditionParent, getDbName(),  table);							
							Object[] rets = new Object[2];
							rets[0] = retFields;
							Object[][] data = getData(retFields, rows);
							rets[1] = data;							
							ret = rets;
						}
					}
					else if(whereIndex < 0 && tables.size() > 0)
					{
						Vector<Row> rows = table.get_Rows();
						Object[] rets = new Object[2];
						rets[0] = retFields;						
						System.out.println("Field " + retFields.size());
						System.out.println("Row " + table.get_Rows().size());
						Object[][] data = getData(retFields, rows);
						rets[1] = data;
						ret = rets;
					}
					else
					{
						ret = "Select failed!";						
					}
					
					
				}
			}
			
			return ret;
		}
		catch(Exception ex)
		{
			System.out.println(ex.getMessage());
			return "Select failed!";
		}
		
	}

	private Object[][] getData(Vector<String> retFields, Vector<Row> rows) {
		Object[][] data = new Object[rows.size()][retFields.size()];
		for(int i = 0 ; i < rows.size(); i++)
		{
			for(int j = 0 ; j < retFields.size(); j++)
			{
				data[i][j] = rows.get(i).get_Fileds().get(retFields.get(j));
			}
		}
		return data;
	}
	
	public boolean isMerge(String sql)
	{
		boolean ret = false;
		ArrayList<Integer> commandIndices = new ArrayList<Integer>();
		Command.countCommand(commandIndices, "select", sql, 0);
		if(commandIndices.size() == 2)
		{
			ret = true;
			System.out.println("is merge");
		}
		
		return ret;
	}
}
